#include "GraceCpp.h"
#include "GraceCppAPI.h"

namespace grace_cpp
{
	namespace file
	{

		void ForceDirectory(const TCHAR *dir)
		{
			TCHAR tmp[MAX_PATH];

			for(size_t i = 0; ; ++i)
			{
				switch(dir[i])
				{
				case PATH_DELIMITER:
				case 0:
					tmp[i] = 0;
					_mkdir(tmp);
					if (0 == dir[i])
						return;
					break;
				default:
					break;
				}
				tmp[i] = dir[i];
			}	
		}

		FileStream::FileStream(const char* FileName, FileMode mode): m_file(NULL)
		{

			this->open(FileName, mode);
		}

		FileStream::~FileStream()
		{
			close();
		}

		bool FileStream::open(const char* FileName, FileMode mode)
		{
			close();

			const char* m = NULL;

			switch(mode)
			{
			case fmOpenRead:
				m = "rb";
				break;
			case fmReadWrite:
				m = "rb+";
				break;
			case fmCreate:
				m = "wb+";
				break;
			}

			m_file = fopen(FileName, m);

			return (m_file != NULL);
		}

		bool FileStream::open(const wchar_t* FileName, FileMode mode)
		{
			close();

			const wchar_t* m = NULL;

			switch(mode)
			{
			case fmOpenRead:
				m = L"rb";
				break;
			case fmReadWrite:
				m = L"rb+";
				break;
			case fmCreate:
				m = L"wb+";
				break;
			}

			m_file = _wfopen(FileName, m);

			return (m_file != NULL);
		}

		bool FileStream::opened()
		{
			return (m_file != NULL);
		}

		void FileStream::close()
		{
			if (m_file)
			{
				fclose(m_file);
				m_file = NULL;
			}
		}

		size_t FileStream::size()
		{
			assert(m_file);
			long bookmark = ftell(m_file);
			fseek(m_file, 0, SEEK_END);
			size_t result = ftell(m_file);
			fseek(m_file, bookmark, SEEK_SET);
			return result;
		}

		void FileStream::pos(size_t offset)
		{
			assert(m_file);

			if (m_file)
				fseek(m_file, offset, SEEK_SET);
		}

		size_t FileStream::pos()
		{
			assert(m_file);
			return (size_t)ftell(m_file);
		}

		void FileStream::seek(SeekOrigin origin, size_t offset)
		{
			assert(m_file);

			if (m_file)
				fseek(m_file, offset, origin);
		}

		size_t FileStream::read(void* buf, size_t len)
		{
			return fread(buf, 1, len, m_file);
		}

		size_t FileStream::write(const void* buf, size_t len)
		{
			return fwrite(buf, 1, len, m_file);
		}

	}
}